#! /usr/bin/python

#* ========================================================================= *#
#* ------------------------------------------------------------------------- *#
##
##  \file        prefs.py
##  \date        November 2011
##  \author      TNick
##
##  \brief        Script for dealing with preferences in literate programming
##
##
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @n
## Please read README and COPYING in root folder @n
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @n
##
#* ------------------------------------------------------------------------- *#
#* ========================================================================= *#
##
##
##
##
#*  INCLUDES    ------------------------------------------------------------ *#

import    subprocess
import    fileinput, string, sys, time
import    os
import    platform
from      time import gmtime, strftime
from      scriptlib import read_dat_file
from      scriptlib import walkDirTree
from      scriptlib import needsUpdate
from      scriptlib import writeFile

#*  INCLUDES    ============================================================ *#
##
##
##
##
#*  DATA    ---------------------------------------------------------------- *#

g_s_defin_header = '''
/**
    This file was generated by the script located in tools/scripts/prefs.py,
    based on the content of source/preferences/prefs.dat.

    If you change this file directly, make sure to also update prefs.dat.

    \\author        prefs.py
*/


/**
*    @brief    unique identificators for various preferences
*/
typedef enum        {

    ID_INVALID = -1,

'''


g_s_defin_footer = '''

    
    ID_MAX_VAL /**< highest assigned value */

}  PrefIds;


'''

g_s_default_header = '''

/**
    This file was generated by the script located in tools/scripts/prefs.py,
    based on the content of source/preferences/prefs.dat.

    If you change this file directly, make sure to also update prefs.dat.

    \\author        prefs.py
*/
#include <aom.h>

#include "prefs.h"

'''


g_s_default_footer = '''

'''

g_s_names_header = '''


const char *            pref_names_[] = {

'''

g_s_names_footer = '''
    ""
};

'''

#*  DATA    ================================================================ *#
##
##
##
##
#*  FUNCTIONS    ----------------------------------------------------------- *#


#* ------------------------------------------------------------------------- *#
def    save_elem_definition( inp_list, label, init_val ):
    """ saves definitions
    
    0 - First row is the ID
    1 - Second row - the type (int, str, real)
    2 - Third row - default value
    3 - Fourth row - description
    
    """

    str_out = ""

    start_mark = "PREF_ID_FIRST_" + label
    end_mark = "PREF_ID_LAST_" + label

    str_out = str_out + "\n\n" + "\t/* --- === " + label + "S === --- */\n\t" + \
    "/** first item in this group */\n\t" + start_mark + " = " + init_val + ",\n\n"

    llst = len( inp_list )
    if ( llst == 0 ):
        str_out = str_out + "\t/** Last item in this group */\n\t" + end_mark + " = " + start_mark + ",\n\n"
    else:
        # the description for first
        str_out = str_out + "\t/** " + inp_list[0][3] + " */\n\t"
        # the id for first needs to be adjusted
        str_out = str_out + inp_list[0][0] + " = " + start_mark + ",\n"

        j = 1 # for all except the first
        while ( j < llst ):
            # the description and the id
            str_out = str_out + "\t/** " + inp_list[j][3] + " */\n\t" + inp_list[j][0] + ",\n"
            j = j + 1

        # ending marker to be able to compute number of items
        str_out = str_out + "\n\t/** Last item in this group */\n\t" + \
        end_mark + " = " + inp_list[llst-1][0] + ",\n\n\n"

    return str_out

#* ========================================================================= *#

#* ------------------------------------------------------------------------- *#
def    save_elem_defaults_s( inp_list ):
    """ saves definitions
    
    0 - First row is the ID
    1 - Second row - the type (int, str, real)
    2 - Third row - default value
    3 - Fourth row - description
    
    """

    str_out = ""

    str_out = str_out + "\n\n" + "\t/* --- === STRINGS === --- */\n\n" + \
        "const char *\t\tdefaults_s_[PREFS_COUNT_STRINGS] = {\n"

    for itr in inp_list:
        str_out = str_out + "\t\"" + itr[2] + "\",\n"

    if ( len( str_out ) > 2 ):
        str_out = str_out[:-2]

    str_out = str_out + "\n};\n\n"
    return str_out

#* ========================================================================= *#

#* ------------------------------------------------------------------------- *#
def    save_elem_defaults_i( inp_list ):
    """ saves definitions
    
    0 - First row is the ID
    1 - Second row - the type (int, str, real)
    2 - Third row - default value
    3 - Fourth row - description
    
    """

    str_out = ""

    str_out = str_out + "\n\n" + "\t/* --- === INTEGERSS === --- */\n\n" + \
        "AOM_INT64\t\tdefaults_i_[PREFS_COUNT_INTS] = {\n"

    for itr in inp_list:
        if len( itr[2] ) != 0:
            str_out = str_out + "\t" + itr[2] + ",\n"
        else:
            str_out = str_out + "\t0,\n"

    if ( len( str_out ) > 2 ):
        str_out = str_out[:-2]

    str_out = str_out + "\n};\n\n"
    return str_out

#* ========================================================================= *#

#* ------------------------------------------------------------------------- *#
def    save_elem_defaults_r( inp_list ):
    """ saves definitions
    
    0 - First row is the ID
    1 - Second row - the type (int, str, real)
    2 - Third row - default value
    3 - Fourth row - description
    
    """

    str_out = ""

    str_out = str_out + "\n\n" + "\t/* --- === REALS === --- */\n\n" + \
        "double\t\tdefaults_r_[PREFS_COUNT_REALS] = {\n"
    for itr in inp_list:
        if len( itr[2] ) != 0:
            str_out = str_out + "\t" + itr[2] + ",\n"
        else:
            str_out = str_out + "\t0.0,\n"

    if ( len( str_out ) > 2 ):
        str_out = str_out[:-2]

    str_out = str_out + "\n};\n\n"
    return str_out

#* ========================================================================= *#

#* ------------------------------------------------------------------------- *#
def    save_elem_names( inp_list, label ):
    """ saves definitions
    
    0 - First row is the ID
    1 - Second row - the type (int, str, real)
    2 - Third row - default value
    3 - Fourth row - description
    
    """

    str_out = ""

    str_out = str_out + "\n\n" + "\t/* --- === " + label + "S === --- */\n\n"

    for itr in inp_list:
        str_out = str_out + "\t\"" + itr[0] + "\",\n"

    return str_out

#* ========================================================================= *#

#* ------------------------------------------------------------------------- *#
def    createPreferences( table, out_path ):
    """ recieves a table of preferences; gen gerates the files from it
    
    First line is the header.
    0 - First row is the ID
    1 - Second row - the type (int, str, real)
    2 - Third row - default value
    3 - Fourth row - description
    
    """
    
    part_l_strings = []
    part_l_ints = []
    part_l_reals = []
    
    # separate content
    i = 0
    while ( i < len( table )-1 ):
        i = i + 1
        e_type = table[i][1].upper()
        if ( e_type == "STRING" ):
            part_l_strings.append( table[i] )
        elif ( e_type == "STR" ):
            part_l_strings.append( table[i] )
        elif ( e_type == "S" ):
            part_l_strings.append( table[i] )
            
        elif ( e_type == "INTEGER" ):
            part_l_ints.append( table[i] )
        elif ( e_type == "INT" ):
            part_l_ints.append( table[i] )
        elif ( e_type == "I" ):
            part_l_ints.append( table[i] )
            
        elif ( e_type == "REAL" ):
            part_l_reals.append( table[i] )
        elif ( e_type == "R" ):
            part_l_reals.append( table[i] )
        else:
            print "Unknown table type in preferences" + e_type
            raise KeyError
            
    str_defin = ""
    str_defin = str_defin + save_elem_definition( part_l_strings, "STRING", "0" )
    str_defin = str_defin + save_elem_definition( part_l_ints, "INTEGER", "1000" )
    str_defin = str_defin + save_elem_definition( part_l_reals, "REAL", "2000" )
    str_defin = g_s_defin_header + str_defin + g_s_defin_footer

    str_default = ""
    str_default = str_default + save_elem_defaults_s( part_l_strings )
    str_default = str_default + save_elem_defaults_i( part_l_ints )
    str_default = str_default + save_elem_defaults_r( part_l_reals )
    str_default = g_s_default_header + str_default + g_s_default_footer

    str_names = ""
    str_names = str_names + save_elem_names( part_l_strings, "STRING" )
    str_names = str_names + save_elem_names( part_l_ints, "INTEGER" )
    str_names = str_names + save_elem_names( part_l_reals, "REAL" )
    str_names = g_s_names_header + str_names + g_s_names_footer

    # write output
    if ( os.path.exists( out_path ) == False ):
        os.makedirs( out_path )
    if ( writeFile( \
           os.path.join( out_path, "prefs_defs.h" ), \
           str_defin, \
           "Definitions" ) == False ): return -1
    if ( writeFile( \
           os.path.join( out_path, "prefs_data.c" ), \
           str_default + str_names, \
           "Prefs source" ) == False ): return -1

       
    return 0

#* ========================================================================= *#

#* ------------------------------------------------------------------------- *#
def    main():
    """ Main function that is called when the module is loaded by itself
    """

    print "This module is not designed to be run independently!" 
    return 0

#* ========================================================================= *#

if __name__ == "__main__":
    sys.exit( main() )
    
#*  FUNCTIONS    =========================================================== *#
##
##
##
##
#* ------------------------------------------------------------------------- *#
#* ========================================================================= *#
